﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Data;
using System.Data.SqlClient;

using SIPO.Library;
using SIPO.Library.DomainObject.Administration.UserManagement;
using SIPO.Library.Enum;
using SIPO.Library.Interfaces;

namespace SIPO.Library.DataAccess.Administration.UserManagement
{
    public partial class recMenuRepo : ISearchable<recMenu>
    {
        public List<recMenu> GetHierarchyList(string parameters)
        {
            List<recMenu> tt = new List<recMenu>();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    string hierarchyData = @"
                        WITH n(MenuID, name,  Url, OrderSeq, Level, parent, Paths) AS
                        (
                            SELECT MenuID , MenuName as name, Url, OrderSeq, 0 Level,
                                   ParentMenuID as parent,
                                   '('+CONVERT(VARCHAR (MAX), MenuID)+' - '+CONVERT(VARCHAR (MAX), OrderSeq)+')' Paths
                            FROM master.recMenu
                            WHERE ParentMenuID is null
                                UNION ALL
                            SELECT m.MenuID, m.MenuName, m.Url, m.OrderSeq, Level + 1, m.ParentMenuID,
                                   n.Paths+' * ('+CONVERT (VARCHAR (MAX), case when ISNULL(m.ParentMenuID, 0) = 0 then 0 else m.MenuID END)+' - '+CONVERT(VARCHAR (MAX), m.OrderSeq)+')' as Paths
                            FROM master.recMenu as m, n
                            WHERE n.MenuID = m.ParentMenuID
                        )
                        SELECT  n.MenuID,
                                REPLICATE ('     ' , n.Level) + n.Name AS MenuName,
                                n.Url,
                                n.OrderSeq,
                                n.[Level],
                                n.Parent as ParentMenuID,
                                n.Name as ParentName,
                                Paths FROM n " + parameters + @" ORDER BY paths asc ";

                    cmd.CommandText = hierarchyData;
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        conn.Open();
                        using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                        {
                            while (dr.Read())
                            {
                                recMenu t = new recMenu();
                                t.MenuID = dr[recMenu.Fields.MenuID] == DBNull.Value ? 0 : int.Parse(dr[recMenu.Fields.MenuID].ToString());
                                t.MenuName = dr[recMenu.Fields.MenuName] == DBNull.Value ? string.Empty : dr[recMenu.Fields.MenuName].ToString();
                                t.URL = dr[recMenu.Fields.URL] == DBNull.Value ? string.Empty : dr[recMenu.Fields.URL].ToString();
                                t.ParentMenuID = dr[recMenu.Fields.ParentMenuID] == DBNull.Value ? (int?)null : int.Parse(dr[recMenu.Fields.ParentMenuID].ToString());
                                t.OrderSeq = dr[recMenu.Fields.OrderSeq] == DBNull.Value ? (short?)null : short.Parse(dr[recMenu.Fields.OrderSeq].ToString());

                                t.Level = dr[recMenu.Fields.Level] == DBNull.Value ? 0 : int.Parse(dr[recMenu.Fields.Level].ToString());
                                t.ParentName = dr[recMenu.Fields.ParentName] == DBNull.Value ? string.Empty : dr[recMenu.Fields.ParentName].ToString();

                                tt.Add(t);
                                t.Dispose();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return tt;
        }

        public List<recMenu> GetList(int pageSize, int currentPage, string sortName, string sortOrder, string parameters)
        {
            List<recMenu> tt = new List<recMenu>();
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    int startRow = ((currentPage - 1) * pageSize) + 1;
                    int endRow = (startRow + pageSize);

                    StringBuilder sbQuery = new StringBuilder();
                    sbQuery.AppendFormat(" WITH result_set AS ");
                    sbQuery.AppendFormat(" ( ");
                    sbQuery.AppendFormat("    SELECT ");
                    sbQuery.AppendFormat("      ROW_NUMBER() OVER (ORDER BY {0} {1}) AS [row_number], ", sortName, sortOrder);
                    sbQuery.AppendFormat("      MenuID, MenuName, URL, ParentMenuID, OrderSeq, CreatedBy, CreatedDate, UpdatedBy, UpdatedDate ");
                    sbQuery.AppendFormat("    FROM ");
                    sbQuery.AppendFormat("      [master].recMenu ");
                    sbQuery.AppendFormat("    {0} ", parameters);
                    sbQuery.AppendFormat(" ) ");
                    sbQuery.AppendFormat(" SELECT * FROM result_set WHERE [row_number] BETWEEN {0} AND {1} ", startRow, endRow);

                    cmd.CommandText = sbQuery.ToString();
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        conn.Open();
                        using (SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                        {
                            while (dr.Read())
                            {
                                recMenu t = new recMenu();
                                t.MenuID = dr[recMenu.Fields.MenuID] == DBNull.Value ? 0 : int.Parse(dr[recMenu.Fields.MenuID].ToString());
                                t.MenuName = dr[recMenu.Fields.MenuName] == DBNull.Value ? string.Empty : dr[recMenu.Fields.MenuName].ToString();
                                t.URL = dr[recMenu.Fields.URL] == DBNull.Value ? string.Empty : dr[recMenu.Fields.URL].ToString();
                                t.ParentMenuID = dr[recMenu.Fields.ParentMenuID] == DBNull.Value ? (int?)null : int.Parse(dr[recMenu.Fields.ParentMenuID].ToString());
                                t.OrderSeq = dr[recMenu.Fields.OrderSeq] == DBNull.Value ? (int?)null : int.Parse(dr[recMenu.Fields.OrderSeq].ToString());
                                t.CreatedBy = dr[recMenu.Fields.CreatedBy] == DBNull.Value ? string.Empty : dr[recMenu.Fields.CreatedBy].ToString();
                                t.CreatedDate = dr[recMenu.Fields.CreatedDate] == DBNull.Value ? (DateTime?)null : DateTime.Parse(dr[recMenu.Fields.CreatedDate].ToString());
                                t.UpdatedBy = dr[recMenu.Fields.UpdatedBy] == DBNull.Value ? string.Empty : dr[recMenu.Fields.UpdatedBy].ToString();
                                t.UpdatedDate = dr[recMenu.Fields.UpdatedDate] == DBNull.Value ? (DateTime?)null : DateTime.Parse(dr[recMenu.Fields.UpdatedDate].ToString());
                                tt.Add(t);
                                t.Dispose();
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return tt;
        }

        public object SelectScalar(SQL.Function.Aggregate function, string column, string parameters)
        {
            object _result = null;
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                using (SqlCommand cmd = conn.CreateCommand())
                {
                    StringBuilder sbQuery = new StringBuilder();
                    switch (function)
                    {
                        case SQL.Function.Aggregate.Max:
                            sbQuery.AppendFormat("SELECT MAX({0}) FROM [master].recMenu {1}", column, parameters);
                            break;
                        case SQL.Function.Aggregate.Min:
                            sbQuery.AppendFormat("SELECT MIN({0}) FROM [master].recMenu {1}", column, parameters);
                            break;
                        case SQL.Function.Aggregate.Distinct:
                            sbQuery.AppendFormat("SELECT DISTINCT({0}) FROM [master].recMenu {1}", column, parameters);
                            break;
                        case SQL.Function.Aggregate.Count:
                            sbQuery.AppendFormat("SELECT COUNT({0}) FROM [master].recMenu {1}", column, parameters);
                            break;
                        case SQL.Function.Aggregate.Sum:
                            sbQuery.AppendFormat("SELECT SUM({0}) FROM [master].recMenu {1}", column, parameters);
                            break;
                        case SQL.Function.Aggregate.Avg:
                            sbQuery.AppendFormat("SELECT AVG({0}) FROM [master].recMenu {1}", column, parameters);
                            break;
                        default:
                            // do nothing 
                            break;
                    }

                    cmd.CommandText = sbQuery.ToString();
                    cmd.CommandType = CommandType.Text;
                    try
                    {
                        conn.Open();
                        _result = cmd.ExecuteScalar();
                    }
                    catch (Exception ex)
                    {
                        throw (ex);
                    }
                    finally
                    {
                        if (conn.State == ConnectionState.Open) conn.Close();
                    }
                }
            }
            return _result;
        }

    }

}
